package com.gupao.vip.aio;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

/**
 * AcceptCompletionHandler实例作为handler来接收通知消息
 */
public class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, AsyncTimeServerHandler> {

    @Override
    public void completed(AsynchronousSocketChannel result, AsyncTimeServerHandler attachment) {
        /**
         * 当我们调用java.nio.channels.AsynchronousServerSocketChannel#accept(java.lang.Object, java.nio.channels.CompletionHandler)的
         * accept方法后，如果有新的客户端连接接入，系统将回调我们传入的java.nio.channels.CompletionHandler#completed(java.lang.Object, java.lang.Object)方法，
         * 表示新的客户端已经接入成功，因为一个AsynchronousSocketChannel可以接收成千上万个客户端，所以我们需要继续调用它的accept方法，接收其他的客户端连接，
         * 最终形成一个循环
         */
        attachment.getAsynchronousServerSocketChannel().accept(attachment, this);

        //创建新的ByteBuffer，预分配1M的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        /**
         * 异步读操作
         * 参数说明：
         * ByteBuffer dst：接收缓冲区，用于从异步Channel中读取数据包
         * A attachment：异步Channel携带的附件，通知回调的时候作为入参使用
         * CompletionHandler<Integer,? super A> handler：接收通知回调的业务handler
         */
        result.read(buffer, buffer, new ReadCompletionHandler(result));
    }

    @Override
    public void failed(Throwable exc, AsyncTimeServerHandler attachment) {
        System.err.println(exc.getMessage());
        attachment.getLatch().countDown();
    }
}
